local interceptors = require("config.interceptors");
local lang_utils = require("mvc.utils.lang_utils");
local req_utils = require("mvc.utils.req_utils");
local const = require("mvc.config.const");
local eh = require("mvc.exception_handler");
local resp = require("mvc.resp");
local req = require("mvc.req");

--[[
	拦截器处理器
	拦截器do_before方法按定义顺序执行，do_after方法按反序执行
]]

local interceptor_handler = {
	uri = nil,
};

--[[
	拦截器Hanlder构造方法
	@uri
]]
function interceptor_handler:new(uri)
	local o = {};
	setmetatable(o, self);
	self.__index = self;
	self.uri = uri;
	self.name = req_utils.get_method(uri);
	return o;
end


--[[
	Action执行前执行
]]
function interceptor_handler:do_before()
	local item = nil;
	for i in pairs(interceptors) do
		item = interceptors[i];
		if self:_is_match(item) then
			interceptor_inst = require(item.interceptor);
			local f = lang_utils.reflect_1(interceptor_inst, const.DOB, {req, resp});
			if (f == false) then
				eh.to_error("Interceptor {1} has no method: do_before", {item.interceptor}, exception)
				return;
			end
		end
	end
end


--[[
	Action执行后执行
]]
function interceptor_handler:do_after()
	local item = nil;
	for i = #interceptors, 1, -1 do
		item = interceptors[i];
		if self:_is_match(item) then
			interceptor_inst = require(item.interceptor);
			local f = lang_utils.reflect_1(interceptor_inst, const.DOA, {req, resp});
			if (f == false) then
				eh.to_error("Interceptor {1} has no method: do_after", {item.interceptor}, exception)
				return;
			end
		end
	end
end


--[[
	判断拦截器配置实例是否匹配当前uri
	@item
]]
function interceptor_handler:_is_match(item)
	local mapping = item[const.MAP];
	local exclude = item[const.EXC];
	
	--URI全路径匹配
	if mapping == const.FUP then 
		for i in pairs(exclude) do
			if exclude[i] == self.uri then
				return false;
			end
		end
		return true;
	end
	
	--URI精确匹配
	--精确匹配时是否判断exclude?
	if mapping == self.uri then
		return true;
	end
	
	--URI模糊匹配
	if mapping ~= self.uri then 
		for i in pairs(exclude) do
			if exclude[i] == self.uri then
				return false;
			end
		end
	end
	
	return req_utils.uri_pattern_match(self.uri, mapping);
end

return interceptor_handler;

